Mitsubishi D10V development

Contents|Previous|Next
Mitsubishi D10V development

The following documentation discusses the Mitsubishi D10V processor.

- Compiler support for D10V targets
- Preprocessor symbols for D10V targets
- ABI summary for D10V targets
- Assembler support for D10V targets
- Linker support for D10V targets
- Debugger support for D10V targets
- Standalone simulator for D10V targets
- Overlays support for the D10V targets

Compiler support for D10V targets
For a list of available generic compiler options, see GNU CC command options in Using GNU CC in GNUPro Compiler Tools. In addition, the following D10V-specific command-line options are supported.

`-mint16`
`-mint32`

Makes `int` data 16 or 32 bits. The default is `-mint16`. GCC chooses the appropriate runtime library based on the `-mint16` or the `-mint32` switch.

`-mdouble32`
`-mdouble64`

Makes `double` data 32 or 64 bits. The default is `-mdouble32`. The GCC program chooses the appropriate runtime library based on the `-mdouble32` or `-mdouble64` switch.

`-maddac3`
`-mno-addac3`

Enables (or disables) the use of `addac3` and `subac3` instructions. The `-maddac3` switch also enables the `-maccum` instruction.

`-mno-accum`

Enables (or disables) the use the 32-bit accumulators in compiler-generated code.

`-msmall-insns`
`-mno-small-insns`

Enables (or disables) replacing 1 long instruction with 2 short instructions, where possible. The default is `-msmall-insns`.

`-mcond-move`
`-mno-cond-move`

Enables (or disables) use of conditional moves.
The default is `-mcond-move`.

Preprocessor symbols for D10V targets
By default, the compiler defines the preprocessor symbols, `_` `_D10V_` `_` and `D10V.` If the `-ansi` switch is used with GCC for greater ANSI compatibility, then only `__D10V_` `_` is defined. If `-mint32` is used, `__INT_` `_` is defined as 32, and `_` `_INT_MAX__` as 2147483647; otherwise, `_` `_INT_` `_` is defined as 16, and `_` `_INT_MAX_` `_` as 32767.
ABI summary for D10V targets
The following documentation discusses the Application Binary Interface for the D10V.

- Data types and alignment
- CPU registers
- Register usage
- The stack frame
- Argument passing
- Function return values

Data types and alignment
The following table shows the data type sizes.

`char` : | 1 byte
`short` : | 2 bytes
`int` : | 2 bytes unless `-mint32`, in which case 4 bytes
`long` : | 4 bytes
`long long` : | 8 bytes
`float` : | 4 bytes
`double` : | 4 bytes unless `-mdouble64`, in which case 8 bytes
`long` `double` : | 8 bytes
pointer : | 2 bytes

The stack is aligned to a two-byte boundary. One byte is used for characters (including structure/unions made entirely of `chars`), and two byte alignment for everything else.
CPU registers
The first four 16-bit words are passed in registers, `r0` through `r3`; the remaining words are passed on the stack (top of stack is the fifth word passed). Arguments that are at least 32 bits in size always start in an even register, which means there might be an unused register. If the argument is passed on the stack, there is no extra padding being done. If an argument would normally start in a register, but there are not enough registers to pass the entire argument, it is passed on the stack and remaining registers might be used to pass subsequent arguments.
The following table shows the order in which the compiler allocates registers.

Volatile registers | `r2` , `r3` , `r4` , `r5` , `r6` , `r7` , `r12` , `r13`
Saved registers | `r6` , `r7` , `r8` , `r9` , `r10` , `r11`
Accumulators | `a0` , `a1`

Note:
Do not depend on this order. Instead, use the GCC extension, `asm( )`, and allow the compiler to schedule registers.

Register usage

The following table shows the register usage.

`r0` through `r3` | function arguments/function return
`r4` | static chain register, not preserved across calls
`r5` | not preserved across calls
`r6` through `r11` | preserved across calls
`r12` | not preserved across calls
`r13` | holds return address, not preserved across calls
`r14` | holds constant 0
`r15` | stack pointer, preserved across calls
`a0` through `a1` | preserved across calls

The C compiler does not generate code that uses the control registers. It does not use the accumulators by default, unless you use the `-maccum` or `-maddac3` switches.
The stack frame
The following documentation discusses the stack frame for the D10V.

- The stack grows downwards from high addresses to low addresses.
- A leaf function need not allocate a stack frame if it does not need one.
- A frame pointer need not be allocated.
- The stack pointer shall always be aligned to 2 byte boundaries.

Stack frames for functions that take a fixed number of arguments use the definitions shown in the following chart.
The following chart shows the allocations. The frame pointer (FP) points to the same location as the stack pointer (SP).

Stack frames for functions taking a variable number of arguments use the following definitions. The frame pointer (FP) points to the same location as the stack pointer (SP).

Argument passing
Arguments are passed to a function using first registers and then memory if the argument passing registers are used up. Items passed in registers that are more than 2 bytes must be passed starting in an even register, skipping the odd register if the odd register would have been the next register used. Unused argument registers have undefined values on entry. Adhere to the following rules.

- The first register values are passed in as `r0` and the last register is `r3`.
- For arguments that would normally start in a register, if there are not enough registers used for passing arguments to hold the argument, the argument will be passed entirely on the stack.

Function return values
Two byte integers are returned in register, `r0`. Four byte integers and floating values are returned in registers, `r0` and `r1`. Eight byte integers and floating point values are returned in registers, `r0`, `r1`, `r2` and `r3`. By default, `int` values are 2 bytes, and `double` values are 4 bytes. The standard type, `long`, is 4 bytes, and `long double` is 8 bytes.
Assembler support for D10V targets
The following documentation discusses the GNU assembler supported functionality.

- Size modifiers
- Sub-instructions
- Special characters
- Register names
- Predefined symbols
- Addressing modes
- `@word` modifier
- Floating point directives
- Opcodes

For a list of available generic assembler options, see Command-line options in Using `as` in GNUPro Utilities. The D10V version of the assembler has only one machine dependent option.

`-O` (uppercase letter, O)

The D10V can often execute two sub-instructions in parallel. With this option, the GNU assembler attempts to optimize its output by detecting when instructions can be executed in parallel.

Syntax is based upon the syntax in Mitsubishi's D10V Architecture documentation.

#### Size modifiers

The D10V assembler uses the instruction names in the D10V Architecture documentation. However, the names are sometimes ambiguous. There are instruction names that can assemble to a `short` or `long` form opcode. The assembler always picks the smallest form it can. When dealing with a symbol that is not yet defined when a line is being assembled, it always uses the `long` form. If you need to force the assembler to use either the `short` or `long` form of the instruction, you can append either `.s` (`short`) or `.l` (`long`) to it. For example, if you are writing an assembly program and you want to do a branch to a symbol that is defined later in your program, you can use the `bra.s foo` declaration. Both the object-file dumper disassembler and GDB's disassembler appends `.s` or `.l` to instructions that have both `short` and `long` forms.

#### Sub-instructions

The D10V assembler takes a series of instructions as input, either one-per-line, or in the special two-per-line format, (see Special characters). Some of these instructions will be short-form or sub-instructions. Sub-instructions can be packed into a single instruction. The assembler does this automatically but works harder at optimization with the `-O` option. It also detects when it should not pack instructions. For example, when a label is defined, the next instruction will never be packaged with the previous one. Whenever a branch-and-link instruction is called, it will not be packaged with the next instruction so the return address will be valid. The assembler automatically inserts Nop instructions when necessary. If you do not want the assembler to automatically make these decisions, you can control the packaging and execution type (parallel or sequential) with the special execution symbols.

#### Special characters

The D10V assembler supports the characters, `;` (semi-colon symbol) and `#` (pound symbol). Both characters are line comment characters when used in the zero column. The semi-colon may also be used to start a comment anywhere within a line.
Sub-instructions may be executed in order, in reverse-order, or in parallel. Instructions listed in the standard one-per-line format will be executed sequentially. To specify the executing order, use the following symbols:

`->`

Sequential with instruction on the left first.

`<-`

Sequential with instruction on the right first.

`||`

Parallel.

The D10V syntax allows either one instruction per line, one instruction per line with the execution symbol, or two instructions per line; for instance, the following declarations serve as examples:

`abs a1 -> abs r0`

Execute these instructions sequentially. The instruction on the right goes into the right container and is executed second.

`abs r0 <- abs a1`

Execute these reverse-sequentially. The instruction on the right goes into the right container, and is executed first.

`ld2w r2,@r8+||mac a0,r0,r7`

These two instructions are executed in parallel.

`ld2w r2,@r8+||`
`mac a0,r0,r7`

Two-line format. These two instructions are executed in parallel.

`ld2w r2,@r8+`
`mac a0,r0,r7`

Two-line format. These two instructions are executed sequentially. The assembler puts them in the proper containers.

`ld2w r2,@r8+ ->`
`mac a0,r0,r7`

Two-line format. These two instructions are executed sequentially. Same as previous instructions but the second instruction always goes into right container.

The `$` (dollar sign) has no special meaning, and may be used in symbol names.

#### Register names

You can use the predefined symbols, `r0` through `r15`, to refer to the D10V registers. You can also use `sp` as an alias for `r15`. The accumulators are `a0` and `a1`. There are special register-pair names that may optionally be used in opcodes that require even-numbered registers. Register names are not case sensitive.
The following register pairs are used.

`r0-r1`
`r2-r3`
`r4-r5`
`r6-r7`
`r8-r9`
`r10-r11`
`r12-r13`
`r14-r15`

`st2wr2-r3, @r4` is a sample register pair instruction.
Predefined symbols
D10V also has predefined symbols for the following control registers and status bits. These predefined symbols are not recognized by the debugger or the disassembler.

`psw` | Processor Status Word
`bpsw` | Backup Processor Status Word
`pc` | Program Counter
`bpc` | Backup Program Counter
`rpt_c` | Repeat Count
`rpt_s` | Repeat Start address
`rpt_e` | Repeat End address
`mod_s` | Modulo Start address
`mod_e` | Modulo End address
`iba` | Instruction Break Address
`f0` | Flag 0
`f1` | Flag 1
`c` | Carry flag
`cr0-cr15` | Accepted as synonyms for these control registers

#### Addressing modes

The assembler understands the following addressing modes for the D10V.
The symbol, `Rn`, in the following examples refers to any of the specifically numbered registers or register pairs, but not the control registers.

- `Rn`
Register direct

- `@Rn`
Register indirect

- `@Rn +`
Register indirect with post-increment

- `@Rn -`
Register indirect with post-decrement

- `@-SP`
Register indirect with pre-decrement

- `@(disp, Rn )`
Register indirect with displacement

- `addr`
PC relative address (for branch or rep)

- `#imm`
Immediate data (`#` is optional and ignored)

`@word`modifier
Any symbol followed by `@word` will be replaced by the symbol's value shifted right by 2. This is used in situations such as loading a register with the address of a function (or any other code fragment). For example, if you want to load a register with the location of the function, `main`, and then jump to that location, use the following code.

`ldir2,main@word`
`jmpr2`

Floating point directives
Although the D10V has no hardware floating point, the `.float` and `.double` directives generate IEEE floating-point numbers for compatibility with other development tools.
Opcodes
The assembler implements all the standard D10V opcodes. For the only changes, see Size modifiers.
Linker support for D10V targets
For a list of available generic linker options, see Linker scripts in Using `ld` in GNUPro Utilities.

There are no D10V specific linker command line options. See also Linker script.

Linker script
The GNU linker uses a linker script to determine how to process each section in an object file, and how to lay out the executable. The linker script is a declarative program consisting of a number of directives. For instance, the directive, `ENTRY()`, specifies which symbol in the executable will be designated the executable's entry point. Since linker scripts can be complicated to write, the linker includes one built-in script that defines the default linking process.

For the D10V tools, the following linker script is the default. Although this script is somewhat lengthy, it is a generic script that will support all ELF situations. In practice, sections like `.rela.dtors` are unlikely to be generated when compiling using embedded ELF tools.

    OUTPUT_FORMAT("elf32-d10v", "elf32-d10v", "elf32-d10v")

    OUTPUT_ARCH(d10v)

    ENTRY(_start)

    SEARCH_DIR( <installation directory path> );

    SECTIONS

    {

    /* Read-only sections, merged into text segment: */

    . = 0x2000004;

    .interp : { *(.interp) }

    .hash : { *(.hash) }

    .dynsym : { *(.dynsym) }

    .dynstr : { *(.dynstr) }

    .rel.text : { *(.rel.text) }

    .rela.text : { *(.rela.text) }

    .rel.data : { *(.rel.data) }

    .rela.data : { *(.rela.data) }

    .rel.rodata : { *(.rel.rodata) }

    .rela.rodata : { *(.rela.rodata) }

    .rel.got : { *(.rel.got) }

    .rela.got : { *(.rela.got) }

    .rel.ctors : { *(.rel.ctors) }

    .rela.ctors : { *(.rela.ctors) }

    .rel.dtors : { *(.rel.dtors) }

    .rela.dtors : { *(.rela.dtors) }

    .rel.init : { *(.rel.init) }

    .rela.init : { *(.rela.init) }

    .rel.fini : { *(.rel.fini) }

    .rela.fini : { *(.rela.fini) }

    .rel.bss : { *(.rel.bss) }

    .rela.bss : { *(.rela.bss) }

    .rel.plt : { *(.rel.plt) }

    .rela.plt : { *(.rela.plt) }

    .plt : { *(.plt) }

    .rodata : { *(.rodata) *(.gnu.linkonce.r*) }

    .rodata1 : { *(.rodata1) }

    /* Adjust the address for the data segment. */

    . = ALIGN(4);

    .data : { *(.data) *(.gnu.linkonce.d*)

    CONSTRUCTORS

    }

    .data1 : { *(.data1) }

    .ctors : { *(.ctors) }

    .dtors : { *(.dtors) }

    .got : { *(.got.plt) *(.got) }

    .dynamic : { *(.dynamic) }

    /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */

    .sdata : { *(.sdata) }

    _edata = .;

    PROVIDE (edata = .);

    __bss_start = .;

    .sbss : { *(.sbss) *(.scommon) }

    .bss : { *(.dynbss) *(.bss)

    *(COMMON)

    }

    _end = . ;

    PROVIDE (end = .);

    /* Stabs debugging sections. */

    .stab 0 : { *(.stab) }

    .stabstr 0 : { *(.stabstr) }

    .stab.excl 0 : { *(.stab.excl) }

    .stab.exclstr 0 : { *(.stab.exclstr) }

    .stab.index 0 : { *(.stab.index) }

    .stab.indexstr 0 : { *(.stab.indexstr) }

    .comment 0 : { *(.comment) }

    /* DWARF debug sections. Symbols in the .debug DWARF section are relative to the beginning of the section so we begin .debug at 0. It's not clear yet what needs to happen for the others. */

    .debug 0 : { *(.debug) }

    .debug_info 0 : { *(.debug_info) }

    .debug_abbrev 0 : { *(.debug_abbrev) }

    .debug_line 0 : { *(.debug_line) }

    .debug_frame 0 : { *(.debug_frame) }

    .debug_srcinfo 0 : { *(.debug_srcinfo) }

    .debug_aranges 0 : { *(.debug_aranges) }

    .debug_pubnames 0 : { *(.debug_pubnames) }

    .debug_sfnames 0 : { *(.debug_sfnames) }

    .line 0 : { *(.line) }

    /* These must appear regardless of . */

    /* This sets the stack to the top of the simulator memory (i.e. top of 64K data space). */

    .stack 0x2007FFE : { _stack = .; *(.stack) }

    .text 0x1000000 :

    {

    *(.init)

    *(.fini)

    *(.text)

    /* .gnu.warning sections are handled specially by elf32.em. */

    *(.gnu.warning)

    *(.gnu.linkonce.t*)

    } =0

    _etext = .;

    PROVIDE (etext = .);

    }

Debugger support for D10V targets
For the available generic debugger options, see Debugging with GDB in GNUPro Debugging Tools. There are no D10V-specific debugger command line options.

The following documentation discusses the use of the GNU debugger, GDB, with the D10V targets.

- Using the trace buffer
- Trace control variables

To specify the D10V simulator as the download target for debugging, use the GDB command, `target sim`, and to specify the D10V board as the download target, use the GDB command, `target remote <port name>`, where `<port name>` designates the port to which the board is attached.
On many Unix platforms substitute the `tty` device name:

`target remote /dev/ttya`

On PC platforms substitute the specific COM port:

`target remote com3`

Using the trace buffer
The following description discusses using the trace buffer access in GDB. For the D10V, trace data means instruction tracing only. Tracing only works with the Dboard_D10V board, not with the simulator.
To start tracing, use the `trace` command. While tracing is on, each time the program stops after being single-stepped or continued, GDB collects the trace buffer that accumulated. This data consists of a set of addresses and counts which represent the number of instructions executed linearly. GDB transfers the data from the target board and keeps it in a buffer managed by GDB. This buffer is called the `host-side trace buffer` or just `trace buffer`, if there is no possibility of confusion with a target's trace buffer.
A host-side trace buffer consists of a set of numbered entries, each of which includes an address and a count. At any time, you may use the `info trace` command to find out how many entries and what those entries contain. You also see whether tracing is currently enabled or disabled.
You may also use `tdisassemble` to display the instructions that are at the locations recorded in the trace buffer. By default, the command disassembles the entire trace buffer; if you supply two arguments, it disassembles only the entries whose numbers fall between the given bounds. The arguments are the numbers assigned to entries in the trace buffer, not addresses.
To end tracing, use the `untrace` command. While tracing is off, the trace buffer is preserved unchanged and you may look at it at any time. However, if you re-enable tracing, GDB will erase the data already in the trace buffer to make space for recording a new instruction trace.

The following test program (`trace.c`) illustrates tracing:

    int a, c;

    main()

    {

    int b, d, i;

    a = 3;

    b = 4;

    c = 456 * (a + b);

    b += c;

    for (i = 0; i < 5; ++i)

    {

    a += d;

    d = b * a;

    }

    }

The following transcript shows these commands in action. This transcript was generated under Unix.

    (gdb) target remote /dev/ttyb

    Remote debugging using /dev/ttyb

    0x1000000 in _start ()

    (gdb) load

    Loading section .data, size 0x190 vma 0x2000004

    Loading section .text, size 0x1a8 vma 0x1000000

    Start address 0x1000000

    Transfer rate: 3296 bits/sec.

    (gdb) break main

    Breakpoint 1 at 0x1000048: file trace.c, line 7.

    (gdb) continue

    Continuing.

    Breakpoint 1, main () at trace.c:7

    7 a = 3;

    (gdb) trace

    Tracing is now on.

    (gdb) step

    8 b = 4;

    (gdb) step

    9 c = 456 * (a + b);

    (gdb) step

    10 b += c;

    (gdb) info trace

    8 entries in trace buffer:

    0: 1 instruction at 0x1000048

    1: 1 instruction at 0x100004c

    2: 1 instruction at 0x1000050

    3: 1 instruction at 0x1000054

    4: 1 instruction at 0x1000058

    5: 1 instruction at 0x100005c

    6: 1 instruction at 0x1000060

    7: 1 instruction at 0x1000064

    Tracing is currently on.

    (gdb) untrace

    Tracing is now off.

    (gdb) tdisassemble

    Dump of trace from 0 to 8:

    7 a = 3;

    0x1000048 <main+8>: ldi.s r2, 0x3 || nop

    0x100004c <main+12>: st r2, @(0x196, r0)8 b = 4;

    0x1000050 <main+16>: ldi.s r2, 0x4 -> st r2, @r11

    9 c = 456 * (a + b);

    0x1000054 <main+20>: ld r2, @(0x196, r0)

    0x1000058 <main+24>: ld r3, @r11 -> add r2, r3

    0x100005c <main+28>: ldi.l r3, 0x1c8

    0x1000060 <main+32>: nop || mul r2, r3

    0x1000064 <main+36>: st r2, @(0x194, r0)

    End of trace dump.

    (gdb)

Later we run through the loop, and then use the arguments, `tdisassemble`, to select portions of the buffer.

    (gdb) info trace

    11 entries in trace buffer:

    0: 8 instructions at 0x1000098

    1: 3 instructions at 0x1000078

    2: 12 instructions at 0x1000088

    3: 3 instructions at 0x1000078

    4: 12 instructions at 0x1000088

    5: 3 instructions at 0x1000078

    6: 12 instructions at 0x1000088

    7: 3 instructions at 0x1000078

    8: 12 instructions at 0x1000088

    9: 4 instructions at 0x1000078

    10: 1 instruction at 0x10000b8

    Tracing is currently on.

    (gdb) tdisassemble 0 3

    Dump of trace from 0 to 3:

    14 d = b * a;

    0x1000098 <main+88>: ld r2, @r11 || nop

    0x100009c <main+92>: ld r3, @(0x196, r0)

    0x10000a0 <main+96>: nop || mul r2, r3

    0x10000a4 <main+100>: st r2, @(0x2, r11)

    11 for (i = 0; i < 5; ++i)

    0x10000a8 <main+104>: ld r2, @(0x4, r11)

    0x10000ac <main+108>: add3 r3, r2, 0x1

    0x10000b0 <main+112>: st r3, @(0x4, r11)

    0x10000b4 <main+116>: bra.s 0x1000078 <main+56> || nop

    0x1000078 <main+56>: ld r2, @(0x4, r11)

    0x100007c <main+60>: cmpi.s r2, 0x5 || nop

    0x1000080 <main+64>: brf0t.l 0x1000088 <main+72>

    13 a += d;

    0x1000088 <main+72>: ld r2, @(0x196, r0)

    0x100008c <main+76>: ld r3, @(0x2, r11)

    0x1000090 <main+80>: add r2, r3 || nop

    0x1000094 <main+84>: st r2, @(0x196, r0)

    14 d = b * a;

    0x1000098 <main+88>: ld r2, @r11 || nop

    0x100009c <main+92>: ld r3, @(0x196, r0)

    0x10000a0 <main+96>: nop || mul r2, r3

    0x10000a4 <main+100>: st r2, @(0x2, r11)

    11 for (i = 0; i < 5; ++i)

    0x10000a8 <main+104>: ld r2, @(0x4, r11)

    0x10000ac <main+108>: add3 r3, r2, 0x1

    0x10000b0 <main+112>: st r3, @(0x4, r11)

    0x10000b4 <main+116>: bra.s 0x1000078 <main+56> || nop

    End of trace dump.

    (gdb)

Trace control variables

There are two GDB trace control variables.

- The variable, `tracedisplay`, controls whether GDB displays trace data as it is accumulated; by default it does not. The command, `set tracedisplay 1`, enables this feature. The data always accumulates, so it is always possible to use a `tdisassemble` command later to see the trace data all at once.
- The variable, `tracesource`, controls the display of source lines corresponding to the trace buffer's addresses; by default, this is enabled. The command, `set tracesource 0`, will disable, and `tdisassemble` will display only assembly language.

Standalone simulator for D10V targets
The simulator supports the Dboard_D10V `IMAP` and `DMAP` registers. The `IMAP0` and `IMAP1` registers are initialized to `0x1000`, `DMAP` is initialized to `0` (zero). To change the map registers, write to `0xff00`, `0xff02`, or `0xff04`, as specified in the D10V Architecture manual in section 9.3.
The simulator allocates unified memory from `0x000000` to `0x50ffff` and `0xfe0000` to `0xffffff`. This corresponds to `IMAP` segment numbers, 0-2 and 127, and `DMAP` segment numbers, 0-23 and 1015-1023. Any attempts to set the `IMAP` or `DMAP` registers to unallocated segments will currently result in simulator errors.
Two run-time command line options are available with the simulator (their examples are depicted using the Unix prompt, `%`).

- `-t` command line option
- `-v` command line option

The `-t` command line option to the standalone simulator turns on instruction level tracing as shown in the following segment.

    % d10v-elf-run -t hello.x

    0x00001d *L: ldi.s r0,0 --- 0x0000 :: 0x0000 F0=0 F1=0 C=0

    0x00001d *R: nop

    0x00001e B: ldi.s r15,65534 --- 0xfffe :: 0xfffe F0=0 F1=0 C=0

    0x00001f B: ldi.s r2,34920 --- 0x8868 :: 0x8868 F0=0 F1=0 C=0

    0x000020 B: ldi.s r3,34952 --- 0x8888 :: 0x8888 F0=0 F1=0 C=0

    0x000021 R: sub r3,r2 0x8888 0x8868 :: 0x002 F0=0 F1=0 C=0

    0x000021 L: mv r4,r3 --- 0x0020 :: 0x0020 F0=0 F1=0 C=0

    0x000022 L: srli r4,2 0x0020 0x0002 :: 0x0008 F0=0 F1=0 C=0

    0x000022 R: mv r1,r0 --- 0x0000 :: 0x0000 F0=0 F1=0 C=0

    0x000023

    . . .

The `-v` command line option prints some simple statistics.

    % d10v-elf-run -v hello.x hello world!

    3 + 4 = 7

    run hello.x

    executed 1458 instructions in the left container, 827 parallel, 15 nops

    executed 1450 instructions in the right container, 827 parallel, 810 nops

    executed 1344 long instructions

    executed 4252 total instructions

Overlays support for the D10V targets

Overlays are sections of code or data which are to be loaded as part of a single memory image, but are to be run or used at a common memory address. At run time, an overlay manager will copy the sections in and out of the runtime memory address. This approach can be useful, for example, when a certain region of memory is faster than another.

The following documentation discusses more of the overlay support.

- Sample runtime overlay manager
- Linker script with overlay functionality
- GDB overlay support
- Breakpoints

Sample runtime overlay manager
This simple, portable runtime overlay manager is provided in the `examples` directory. To access the examples directory, follow the instructions for installing the entire source tree. The full path uses `/usr/cygnus/d10v-<yymmdd>/src/examples`, where `<yymmdd>` is replaced with the release date found on the CD. See Installation and GETTING STARTED for working with GNUPro Toolkit files.
The sample overlay manager may be used as is, or as a prototype to develop a 3rd party overlay manager (or adapt an existing one for use with the GDB debugger). It is intended to be extremely simple, easy to understand, but not particularly sophisticated. Note that since the sample overlay manager copies overlay sections four bytes at a time, it is important that all sections begin on four byte boundaries at their load addresses as well as their runtime addresses.
The overlay manager has a single entry point: a function called `OverlayLoad(ovly_number)`. It looks up the overlay in a table called `ovly_table` to find the corresponding section's load address and runtime address; then it copies the section from its load address into its runtime address. `OverlayLoad` must be called before code or data in an overlay section can be used by the program. It is up to the programmer to keep track of which overlays have been loaded. `_ovly_table` is built by the linker from information provided by the programmer in the linker script.
The example program contains four overlay sections which are mapped into two runtime regions of memory. Sections, `.ovly0` and `.ovly1`, are both mapped into the region starting at `0x1001000`, and sections, `.ovly2` and `.ovly3`, are both mapped into the region starting at `0x1002000`.
Linker script with overlay functionality
To build a program with overlays requires a customized linker script. Our example program is built with the script, `d10vtext.ld`, found in the `examples/overlay` directory. This is just a modified version of the default linker script, with two parts added.

    SECTIONS

    {

    OVERLAY 0x1001000 : AT (0x8000)

    {

    .ovly0 { foo.o(.text) }

    .ovly1 { bar.o(.text) }

    }

    OVERLAY 0x1002000 : AT (0x9000)

    {

    .ovly2 { baz.o(.text) }

    .ovly3 { grbx.o(.text) }

    }

    [...]

We give the `OVERLAY` command two arguments. First, the base address where we want all of the overlay sections to link and run. Second, the address where we want the first overlay section to load. In the following example, `.ovly1`, will load at `0x8000 + SIZEOF(.ovly0)`. For a full description of the `OVERLAY` linker command, see Linker scripts in Using `ld` in GNUPro Utilities. The `OVERLAY` command is really just a syntactic convenience. If you need finer control over where the individual sections will be loaded, you can use the syntax in the following code segement.

    SECTIONS

    {

    .ovly0 0x1001000 : AT (0x8000) { foo.o(.text) }

    .ovly1 0x1001000 : AT (0x9000) { bar.o(.text) }

    .ovly2 0x1002000 : AT (0xA000) { baz.o(.text) }

    .ovly3 0x1002000 : AT (0xB000) { grbx.o(.text) }

    [...]

The second addition to the linker script actually builds `_ovly_table`, which will be used by the sample runtime overlay manager. The following example shows the table having several entries for each overlay, which must be located somewhere in the `.data` section.

     .data :

    {

    [...]

    _ovly_table = .;

    LONG(ABSOLUTE(ADDR(.ovly0)));

    LONG(SIZEOF(.ovly0));

    LONG(LOADADDR(.ovly0));

    LONG(0);

    LONG(ABSOLUTE(ADDR(.ovly1)));

    LONG(SIZEOF(.ovly1));

    LONG(LOADADDR(.ovly1));

    LONG(0);

    LONG(ABSOLUTE(ADDR(.ovly2)));

    LONG(SIZEOF(.ovly2));

    LONG(LOADADDR(.ovly2));

    LONG(0);

    LONG(ABSOLUTE(ADDR(.ovly3)));

    LONG(SIZEOF(.ovly3));

    LONG(LOADADDR(.ovly3));

    LONG(0);

    _novlys = .;

    LONG((_novlys - _ovly_table) / 16);

    [...]

    }

Our example program has four functions; `foo`, `bar`, `baz`, and `grbx`. Each is in a separate overlay section. The functions, `foo` and `bar`, are both linked to run at address, `0x1001000`, while functions, `baz` and `grbx`, are both linked to run at `0x1002000`.
The main program calls `OverlayLoad` once before calling each of the overlaid functions, giving it the overlay number of the respective overlay. The overlay manager, using `_ovly_table` that was built up by the linker script, copies each overlaid function into the appropriate region of memory before it is called.
In order to compile and link the example overlay manager, enter the following input at the prompt, `%`.

    d10v-elf-gcc -g -Td10vdata.ld -oovlydata maindata.c ovlymgr.c

Using GDB's built-in overlay support, we can debug this program even though several of the functions share an address range. After loading the program, give GDB the `overlay auto` command. GDB then detects the actions of the overlay manager on the target, and can step into overlaid functions, show appropriate backtraces, etc. If a symbol is in an overlay that is not currently mapped, GDB will access the symbol from its load address instead of the mapped runtime address (which would currently be holding something else from another overlay).
In the following example, functions, `foo` and `bar`, are in different overlays which run at the same address. We will use GDB's overlay debugging to step into and debug them.

    (gdb) file ovlydata

    Reading symbols from ovlydata...done.

    (gdb) target sim

    Connected to the simulator.

    (gdb) load

    Loading section .ovly0, size 0x2c lma 0x8000

    Loading section .ovly1, size 0x2c lma 0x9000

    Loading section .ovly2, size 0x2c lma 0xa000

    Loading section .ovly3, size 0x2c lma 0xb000

    Loading section .data00, size 0x4 lma 0xc000

    Loading section .data01, size 0x4 lma 0xd000

    Loading section .data02, size 0x4 lma 0xe000

    Loading section .data03, size 0x4 lma 0xf000

    Loading section .data, size 0x214 lma 0x2000004

    Loading section .text, size 0x6e0 lma 0x1000000

    Start address 0x1000000

    Transfer rate: 19872 bits in <1 sec.

    (gdb) overlay auto

    (gdb) overlay list

    No sections are mapped.

    (gdb) info address foo

    Symbol "foo" is a function at address 0x1001000,

    -- loaded at 0x8000 in overlay section .ovly0.

    (gdb) info symbol 0x1001000

    foo in unmapped overlay section .ovly0

    bar in unmapped overlay section .ovly1

    (gdb) info address bar

    Symbol "bar" is a function at address 0x1001000,

    -- loaded at 0x9000 in overlay section .ovly1.

    (gdb) break main

    Breakpoint 1 at 0x1000048: file maindata.c, line 18.

    (gdb) run

    Starting program: ovlydata

    Breakpoint 1, main () at maindata.c:18

    18 OverlayLoad(0);

    (gdb) next

    19 OverlayLoad(4);

    (gdb) next

    20 a = foo(1);

    (gdb) overlay list

    Section .ovly0, loaded at 00008000 - 0000802c, mapped at 01001000 - 0100102c

    Section .data00, loaded at 0000c000 - 0000c004, mapped at 02001000 - 02001004

    (gdb) info symbol 0x1001000

    foo in mapped overlay section .ovly0

    bar in unmapped overlay section .ovly1

The overlay containing function, `foo`, is now mapped.

    (gdb) step

    foo (x=1) at foo.c:6

    6 if (x)

    (gdb) x /i $pc

    0x1001008 <foo+8>: ld r2, @r11 -> cmpeqi.s r2, 0x0

    (gdb) print foo

    $1 = {long int (int)} 0x1001000 <foo>

    (gdb) print bar

    $2 = {long int (int)} 0x9000 <*bar*>

GDB uses labels such as `<*bar*>` (with asterisks) to distinguish overlay load addresses from the symbol's runtime address (where it will be when used by the program).

    (gdb) disassemble

    Dump of assembler code for function foo:

    0x1001000 <foo>: st r11, @-sp -> subi sp, 0x2

    0x1001004 <foo+4>: mv r11, sp -> st r2, @r11

    0x1001008 <foo+8>: ld r2, @r11 -> cmpeqi.s r2, 0x0

    0x100100c <foo+12>: brf0t.l 0x100101c <foo+28>

    0x1001010 <foo+16>: ld2w r2, @(0x1000, r0)

    0x1001014 <foo+20>: bra.l 0x1001024 <foo+36>

    0x1001018 <foo+24>: bra.l 0x1001024 <foo+36>

    0x100101c <foo+28>: ldi.s r2, 0x0 -> ldi.s r3, 0x0

    0x1001020 <foo+32>: bra.l 0x1001024 <foo+36>

    0x1001024 <foo+36>: add3 sp, r11, 0x2

    0x1001028 <foo+40>: ld r11, @sp+ -> jmp r13

    End of assembler dump.

    (gdb) disassemble bar

    Dump of assembler code for function bar:

    0x9000 <*bar*>: st r11, @-sp -> subi sp, 0x2

    0x9004 <*bar+4*>: mv r11, sp -> st r2, @r11

    0x9008 <*bar+8*>: ld r2, @r11 -> cmpeqi.s r2, 0x0

    0x900c <*bar+12*>: brf0t.l 0x901c <*bar+28*>

    0x9010 <*bar+16*>: ld2w r2, @(0x1000, r0)

    0x9014 <*bar+20*>: bra.l 0x9024 <*bar+36*>

    0x9018 <*bar+24*>: bra.l 0x9024 <*bar+36*>

    0x901c <*bar+28*>: ldi.s r2, 0x0 -> ldi.s r3, 0x0

    0x9020 <*bar+32*>: bra.l 0x9024 <*bar+36*>

    0x9024 <*bar+36*>: add3 sp, r11, 0x2

    0x9028 <*bar+40*>: ld r11, @sp+ -> jmp r13

    End of assembler dump.

Since the overlay containing `bar` is not currently mapped, GDB finds `bar` at its load address, and disassembles it there.

    (gdb) finish

    Run till exit from #0 foo (x=1) at foo.c:5

    0x1000060 in main () at maindata.c:20

    20 a = foo(1);

    Value returned is $3 = 324

    (gdb) next

    21 OverlayLoad(1);

    (gdb) next

    22 OverlayLoad(5);

    (gdb) next

    23 b = bar(1);

    (gdb) overlay list

    Section .ovly1, loaded at 00009000 - 0000902c, mapped at 01001000 - 0100102c

    Section .data01, loaded at 0000d000 - 0000d004, mapped at 02001000 - 02001004

    (gdb) info symbol 0x1001000

    foo in unmapped overlay section .ovly0

    bar in mapped overlay section .ovly1

    (gdb) step

    bar (x=1) at bar.c:6

    6 if (x)

    (gdb) x /i $pc

    0x1001008 <bar+8>: ld r2, @r11 -> cmpeqi.s r2, 0x0

Now `bar` is mapped, and `foo` is not. Even though the PC is at the same address as before, GDB recognizes that we are in `bar` rather than `foo`.

    (gdb) disassemble

    Dump of assembler code for function bar:

    0x1001000 <bar>: st r11, @-sp -> subi sp, 0x2

    0x1001004 <bar+4>: mv r11, sp -> st r2, @r11

    0x1001008 <bar+8>: ld r2, @r11 -> cmpeqi.s r2, 0x0

    0x100100c <bar+12>: brf0t.l 0x100101c <bar+28>

    0x1001010 <bar+16>: ld2w r2, @(0x1000, r0)

    0x1001014 <bar+20>: bra.l 0x1001024 <bar+36>

    0x1001018 <bar+24>: bra.l 0x1001024 <bar+36>

    0x100101c <bar+28>: ldi.s r2, 0x0 -> ldi.s r3, 0x0

    0x1001020 <bar+32>: bra.l 0x1001024 <bar+36>

    0x1001024 <bar+36>: add3 sp, r11, 0x2

    0x1001028 <bar+40>: ld r11, @sp+ -> jmp r13

    End of assembler dump.

    (gdb) finish

    Run till exit from #0 bar (x=1) at bar.c:5

    0x100007c in main () at maindata.c:23

    23 b = bar(1);

    Value returned is $4 = 309

In the following example, the `bazx` and `grbxx` variables are both mapped to the same runtime address. We will see that with the automatic overlay debugging mode, GDB always knows which variable is using that address.

    (gdb) info addr bazx

    Symbol "bazx" is static storage at address 0x2002000,

    -- loaded at 0xe000 in overlay section .data02.

    (gdb) info sym 0x2002000

    bazx in unmapped overlay section .data02

    grbxx in unmapped overlay section .data03

    (gdb) info addr grbxx

    Symbol "grbxx" is static storage at address 0x2002000,

    -- loaded at 0xf000 in overlay section .data03.

    (gdb) break baz

    Breakpoint 2 at 0x1002008: file baz.c, line 6.

    (gdb) break grbx

    Breakpoint 3 at 0x1002008: file grbx.c, line 6.

Note that the two breakpoints are actually set at the same address, yet GDB will correctly distinguish between them when it hits them. If only one overlay function has a breakpoint on it, GDB will not stop at that address in other overlay functions.

    (gdb) continue

    Continuing.

    Breakpoint 2, baz (x=1) at baz.c:6

    6 if (x)

    (gdb) print &bazx

    $5 = (long int *) 0x2002000

    (gdb) x /d &bazx

    0x2002000 <bazx>:317

    (gdb) print &grbxx

    $6 = (long int *) 0xf000

    (gdb) continue

    Continuing.

    Breakpoint 3, grbx (x=1) at grbx.c:6

    6 if (x)

    (gdb) print &grbxx

    $7 = (long int *) 0x2002000

    (gdb) x /d &grbxx

    0x2002000 <grbxx>:435

    (gdb) print &bazx

    $8 = (long int *) 0xe000

    (gdb) x /d &bazx

    0xe000 <*bazx*>:317

GDB overlay support

GDB provides special functionality for debugging a program that is linked using the overlay mechanism of `ld`, the GNU linker. In such programs, an overlay corresponds to a section with a load address that is different from its runtime address. GDB can provide `manual` overlay debugging for any program linked in such a way (providing that the overlays all reside somewhere in memory). Automatic overlay debugging is also provided for the Cygnus Sample Overlay Manager.

    overlay manual

    overlay map < section-name >

    overlay unmap < section-name >

    overlay list

    overlay off

The manual mode requires input from the user to specify what overlays are mapped into their runtime address regions at any given time. The command ` `OVERLAY MAP` ' informs GDB that the overlay has been mapped by the target into its shared runtime address range. The command ` `overlay unmap` ' informs GDB that the overlay is no longer resident in its runtime address region, and must be accessed from the load-time address region. If two overlays share the same runtime address region, then mapping one implies unmapping the other.

    overlay auto

    overlay list

    overlay off

Automatic overlay debugging support in GDB works with the runtime overlay manager provided in the `examples` directory.

When this mode is activated, GDB will automatically read and interpret the data structures maintained in target memory by the overlay manager. To learn what overlays are mapped at any time, use the command, `overlay list`. Whenever the target program is allowed to run (by the `STEP` command), GDB will refresh its overlay map by reading from the target's overlay tables.

The automatic mapping may be temporarily overridden by the commands, `overlay map` and `overlay unmap`, but these mappings will last only until the next time the target is allowed to run. To explicitly take control of GDB's overlay mapping, switch to the `overlay manual` mode.

When GDB's overlay support (either manual or auto) is active, GDB's concept of a symbol's address is controlled by which overlays are mapped into which memory regions. For instance, if you use the command, `PRINT`, to get a variable that is in an overlay which is currently mapped (that is located in its runtime address region) GDB will fetch the variable's memory from the runtime address. If the variable's overlay is currently not mapped, GDB will fetch it from its load-time address.

Similarly, if you disassemble a function that is in an unmapped overlay, or use a symbol's address to examine memory, GDB will fetch the memory from the symbol's load-time address range instead of the runtime range. If GDB's output contains labels that are relative to an overlay's load-time address instead of the runtime address, the labels will be distinguished like this:

    (gdb) overlay map .ovly0

    (gdb) x /x foo

    0x1001000 <foo>: 0x76bf81e5

    (gdb) overlay unmap .ovly0

    (gdb) x /x foo

    0x8000 <*foo*>: 0x76bf81e5

The extra asterisks around the label, `foo`, may be interpreted as meaning that this is where `foo` is presently, but not where it will be when it is in use by the target program.
The `info address` command can tell you what overlay a symbol is in, as well as where it is loaded and mapped. The `info symbol` command can list all of the symbols that are mapped to an address.

    (gdb) info address foo

    Symbol "foo" is a function at address 0x1001000

    -- loaded at 0x8000 in overlay section .ovly0.

    (gdb) info symbol 0x1001000

    foo in mapped overlay section .ovly0

    bar in unmapped overlay section .ovly1

Breakpoints
So long as the overlay sections are located in RAM rather than ROM, GDB can set breakpoints in them. The breakpoints work by inserting trap instructions into the load-time address region. When the overlay is mapped into the runtime region, the trap instructions are mapped along with it, and when executed, cause the target program to break out to the debugger. If the overlay regions are located in ROM, you can only set breakpoints in them after they have been mapped into the runtime region in RAM.

Top|Contents|Previous|Next